﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace GarbageCollectorTest
{
	public class TSQueue<T> : Queue<T>
	{
        private AutoResetEvent _lock = new AutoResetEvent(false);
		public new T Dequeue()
		{
			try
			{

				Monitor.Enter(this);

				while (Count == 0)
				{
					// wait to reacquire the lock since there is no work to be performed
					// note that if there are N instance of this, then only one will pass the while loop if only one job is added
					Monitor.Wait(this);
				}
				T val = base.Dequeue();
				// we are quaranteed a value here, so no need to check, just release the monitor
				Monitor.PulseAll(this);
				Monitor.Exit(this);
				return val;
			}
			catch (Exception e) 
			{
				Console.Write(String.Format("dequeue error {0}", e.Message));
			  return default(T);
			}
		}
		public new void Enqueue(T obj)
		{
			try
			{
				Monitor.Enter(this);
				
				base.Enqueue(obj);
				// let everyone know that we have a value
				Monitor.PulseAll(this);
				Monitor.Exit(this);
			}
			catch(Exception e)
			{
				Console.Write(String.Format("enqueue error {0}", e.Message));
			}
		}
        public new void Clear()
        {
            try
            {
                Monitor.Enter(this);
                base.Clear();
                // let everyone know that we have a value
                Monitor.PulseAll(this);
                Monitor.Exit(this);
            }
            catch (Exception e)
            {
                Console.Write(String.Format("enqueue error {0}", e.Message));
            }

        }
	}
}